﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OptionsBase.cs" company="StyleCop for ReSharper Development Team">
//   Copyright (c) StyleCop for ReSharper Development Team. All rights reserved.
// </copyright>
// <summary>
//   Defines the OptionsBase type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace StyleCop.For.ReSharper.CodeCleanup.Options
{
    #region Using Directives

    using System.Linq;
    using System.Reflection;

    using Microsoft.StyleCop;

    using StyleCop.For.ReSharper.Core;
    using StyleCop.For.ReSharper.Diagnostics;

    #endregion

    /// <summary>
    /// Defines the base options class for SCfR#. 
    /// </summary>
    public abstract class OptionsBase
    {
        #region Constants and Fields

        private AddInPropertyCollection analyzerSettingsProperties;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the name of the analyzer as defined in StyleCop settings. 
        /// </summary>
        /// <value>
        /// The name of the analyzer.
        /// </value>
        protected abstract string AnalyzerName { get; }

        #endregion

        #region Methods

        /// <summary>
        /// Initializes the properties defaults from StyleCop settings.
        /// It assumes that the first 6 chars of each property are the code (ie: SAxxxx) and the rest matchs the name as defined in StyleCop settings
        /// (ex: SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine =&gt;  CurlyBracketsForMultiLineStatementsMustNotShareLine shuld be the name in StyleCop settings). 
        /// </summary>
        protected void InitPropertiesDefaults()
        {
            var styleCopSettings = Utils.GetStyleCopSettings();
            if (styleCopSettings != null)
            {
                this.analyzerSettingsProperties = styleCopSettings.AnalyzerSettings.FirstOrDefault(n => n.AddIn.Id == this.AnalyzerName);
            }

            var propertyInfos = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var propertyInfo in propertyInfos)
            {
                if (propertyInfo.PropertyType == typeof(bool))
                {
                    var settingsProperty = propertyInfo.Name.Substring(6);
                    var propertyValue = this.IsPropertyEnabled(settingsProperty);

                    StyleCopTrace.Info("Property " + propertyInfo.Name + "-> " + propertyValue);
                    propertyInfo.SetValue(this, propertyValue, null);
                }
            }
        }

        /// <summary>
        /// Determines whether a property is enabled in StyleCop settings. 
        /// Default to true if property isn't defined in StyleCop settings. 
        /// </summary>
        /// <param name="propertyName">
        /// The property.
        /// </param>
        /// <returns>
        /// <c>true</c> if the property is enabled; otherwise, <c>false</c>.
        /// </returns>
        protected bool IsPropertyEnabled(string propertyName)
        {
            if (this.analyzerSettingsProperties == null)
            {
                return true;
            }

            var property = this.analyzerSettingsProperties[propertyName + "#Enabled"] as BooleanProperty;

            if (property != null)
            {
                return property.Value;
            }
           
            var defaultPropertyDecriptor = this.analyzerSettingsProperties.AddIn.PropertyDescriptors[propertyName + "#Enabled"] as PropertyDescriptor<bool>;

            if (defaultPropertyDecriptor != null)
            {
                return defaultPropertyDecriptor.DefaultValue;
            }

            return true;
        }

        #endregion
    }
}